using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Data;
using System.Xml;
using Castle.ActiveRecord;
using NHibernate.Criterion;

using Pampa.CRUD.Core;
using Pampa.CRUD.Exceptions;

using Pampa.Grid.Core;
using Pampa.Grid.Core.Filters;
using Pampa.Grid.Data;
using Pampa.Grid.Exceptions;
using Pampa.MVC.Models;

namespace Pampa.MVC.Data
{
    public class GridDataReaderCastle : GridDataReaderEntityBase
    {
        public GridDataReaderCastle(string entityName) : base(entityName)
        {
        }

        protected override object[] GetEntities(Order[] order, params ICriterion[] criteria)
        {
            Type type = Type.GetType(this.EntityName);

            if (type.GetInterface("IPampaViewModel") != null)
            {
                var entityType = ((IPampaViewModel)Activator.CreateInstance(type)).GetInnerEntity().GetType();
                var lentities = (object[])ActiveRecordMediator.FindAll(entityType, order, criteria);
                return Wrap(lentities);
            }
            else
            {
                return (object[])ActiveRecordMediator.FindAll(type, order, criteria);
            }
        }

        protected override object[] GetEntities(int firstResult, int maxResult, Order[] order, params ICriterion[] criteria)
        {
            Type type = Type.GetType(this.EntityName);

            if (type.GetInterface("IPampaViewModel") != null)
            {
                var entityType = ((IPampaViewModel)Activator.CreateInstance(type)).GetInnerEntity().GetType();
                var lentities = (object[])ActiveRecordMediator.SlicedFindAll(entityType, firstResult, maxResult, order, criteria);
                return Wrap(lentities);
            }
            else
            {
                return (object[])ActiveRecordMediator.SlicedFindAll(type, firstResult, maxResult, order, criteria);
            }
        }

        protected override int CountEntities(params ICriterion[] criteria)
        {
            Type type = Type.GetType(this.EntityName);

            if (type.GetInterface("IPampaViewModel") != null)
            {
                var entityType = ((IPampaViewModel)Activator.CreateInstance(type)).GetInnerEntity().GetType();
                return ActiveRecordMediator.Count(entityType, criteria);
            }
            else
            {
                return ActiveRecordMediator.Count(type, criteria);
            }
        }

        private IPampaViewModel[] Wrap(object[] aentities)
        {
            var type = Type.GetType(this.EntityName);

            var viewModels = new List<IPampaViewModel>();

            foreach (var entity in aentities)
            {
                var viewModel = (IPampaViewModel)Activator.CreateInstance(type);
                viewModel.SetInnerEntity(entity);
                viewModels.Add(viewModel);
            }

            return viewModels.ToArray();
        }
    }
}
